package v1

import (
	"time"
)

type Config struct {
	// description: |
	//   集群级别的配置信息，其中 `db_port` 和 `ssh_option` 字段是 **可重用字段**
	//
	//   **可重用字段**
	//     如果实例级别设置了该字段，则对应实例使用实例级别的值；
	//     如果实例级别未配置该字段，则继承 global 级别的字段的值。
	// supported_from: v0.1
	Global *Global `yaml:"global" json:"global"`
	// description: |
	//   集群内的数据库实例服务器配置信息
	// supported_from: v0.1
	DBServers []*DBServer `yaml:"db_servers" json:"db_servers"`
	// description: 集群内的CM服务部署机器列表
	// examples:
	// supported_from: v0.5
	CMServers []*CMServer `yaml:"cm_servers" json:"cm_servers"`
	// docgen:nodoc
	CreateTime time.Time `yaml:"create_time,omitempty" json:"create_time,omitempty"`
	// docgen:nodoc
	UpdateTime time.Time `yaml:"update_time,omitempty" json:"update_time,omitempty"`
	// docgen:nodoc
	Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
}

// Global 定义配置文件中全局参数
type Global struct {
	// description: |
	//  集群名称，PTK管理的集群的唯一标识
	// supported_from: v0.1
	ClusterName string `yaml:"cluster_name" json:"cluster_name"`
	// description: |
	//  运行数据库的操作系统用户名
	//  如果想一套主备在同一个服务器上部署，需在实例级别设置不同的用户来隔离环境
	//  默认为："omm"
	// supported_from: v0.1
	User string `yaml:"user,omitempty" json:"user,omitempty"`
	// description: |
	//   运行数据库的操作系统用户组
	//   默认和操作系统用户同名
	// supported_from: v0.1
	Group string `yaml:"group,omitempty" json:"group,omitempty"`
	// description: |
	//   运行数据库的操作系统用户密码
	//   该字段不支持明文填写，需使用 ptk encrypt 加密
	//   默认为空，不设置
	// supported_from: v0.1
	UserPassword string `yaml:"user_password,omitempty" json:"user_password,omitempty"`
	// description: |
	//   数据库的初始用户密码，若配置文件中未填写，会在安装时通过交互式要求输入
	//   该字段不支持明文填写，需使用 ptk encrypt 加密
	// supported_from: v0.1
	DBPassword string `yaml:"db_password,omitempty" json:"db_password,omitempty"`
	// description: |
	//   数据库的运行端口
	//   如果在单个服务器上部署主备，需在实例级别设置不同的端口号
	//   默认值: 26000
	// supported_from: v0.1
	DBPort int `yaml:"db_port,omitempty" json:"db_port,omitempty"`
	// description: |
	//   数据库安装的基础目录，一般建议指定到配置文件中 ssh 用户可访问的目录下的路径，让PTK自动创建。
	//   如果 PTK 在执行安装时使用的为非 root 用户的话，普通用户没有权限在 /opt 目录下创建目录，所以默认值 `/opt/mogdb` 会出现无权创建的问题，需用户指定一个执行用户可访问的路径。
	//   指定该目录后，app_dir，data_dir，log_dir和tool_dir 参数中若未配置的，PTK 会自动在该安装目录下会创建对应的目录；
	//   无特殊要求情况下，我们推荐用户在安装时仅设置该参数即可
	//   注意：若在单机上部署集群时，需在实例级别设置不同的安装目录
	//   默认值: "/opt/mogdb"
	// supported_from: v0.1
	BaseDir string `yaml:"base_dir,omitempty" json:"base_dir,omitempty"`
	// description: |
	//   数据库部署文件、启动脚本和配置文件的存放路径
	//   默认值: "${base_dir}/app"
	// supported_from: v0.1
	AppDir string `yaml:"app_dir,omitempty" json:"app_dir,omitempty"`
	// description: |
	//   数据库数据存储目录
	//   默认值: "${base_dir}/data"
	// supported_from: v0.1
	DataDir string `yaml:"data_dir,omitempty" json:"data_dir,omitempty"`
	// description: |
	//   数据库运行日志和操作日志存储目录
	//   默认值: "${base_dir}/log"
	// supported_from: v0.1
	LogDir string `yaml:"log_dir,omitempty" json:"log_dir,omitempty"`
	// description: |
	//   数据库工具目
	ToolDir string `yaml:"tool_dir,omitempty" json:"tool_dir,omitempty"`
	// description: |
	//   数据库临时目录
	//   默认值: 如果base_dir 不为空，值为 ${base_dir}/tmp, 否则为 /tmp
	// supported_from: v0.1
	TmpDir string `yaml:"tmp_dir,omitempty" json:"tmp_dir,omitempty"`
	// description: |
	//   [v0.7及后面版本废弃] 该参数已废弃，不再生效，请切换超级用户后手动设置 `kernel.core_pattern`
	// supported_from: v0.1
	CoreFileDir string `yaml:"core_file_dir,omitempty" json:"core_file_dir,omitempty"`
	// description: |
	//   SSH 登录信息
	//   不设置时为本地执行
	// supported_from: v0.1
	SSHOption *SSHOption `yaml:"ssh_option,omitempty" json:"ssh_option,omitempty"`
	// description: |
	//   用户自定义配置 gs_initdb 初始化数据库时的参数。
	//   特别地, 如果用户未配置 locale 参数, PTK 默认会设置 no-locale
	//   支持的参数列表请查看 gs_initdb 工具[文档](https://docs.mogdb.io/zh/mogdb/v3.0/5-gs_initdb)
	// examples:
	//   - name: gs_initdb_opts 填写示例
	//     value: '[]string{"--locale=LOCALE", "-E=UTF-8"}'
	// supported_from: v0.3
	GsInitdbOpts []string `yaml:"gs_initdb_opts,omitempty" json:"gs_initdb_opts,omitempty"`
	// description: |
	//   额外新增 HBA 条目列表
	// supported_from: v1.5
	ExtraHBAConf []*HBAConf `yaml:"extra_hba_conf,omitempty" json:"extra_hba_conf,omitempty"`
	// description: |
	//   MogDB 高可用组件 CM 配置信息，若不使用 CM 组件，则无需填写该字段
	//   仅在数据库版本 3.0 及以上生效
	// supported_from: v0.4
	CMOption *CMOption `yaml:"cm_option,omitempty" json:"cm_option,omitempty"`

	// description: |
	//   用户可根据需要增加特定的环境变量，在 global 中设置会对所有实例生效，
	//   实例级别可单独设置，如果存在相同的 key，实例级的会覆盖 global 中的值
	// supported_from: v1.2.0
	EnvMap map[string]string `yaml:"env_map,omitempty" json:"env_map,omitempty"`
}

type DBServer struct {
	// description: |
	//   一个集群中唯一标识数据实例的名称，该值将会写入配置 application_name
	//   默认值：dn_<id>
	// supported_from: v1.0
	DnName string `yaml:"dn_name,omitempty" json:"dn_name,omitempty"`
	// description: |
	//   数据库实例服务器 IP (仅支持 IPv4)
	// supported_from: v0.1
	Host string `yaml:"host" json:"host"`
	// description: |
	//  运行数据库的操作系统用户名
	//  如果想一套主备在同一个服务器上部署，该字段需设置为不同的用户
	//  默认和 global.user 配置一致
	// supported_from: v0.5
	User string `yaml:"user,omitempty" json:"user,omitempty"`
	// description: |
	//   运行数据库的操作系统用户组
	//   默认和 global.group 配置一致
	// supported_from: v0.5
	Group string `yaml:"group,omitempty" json:"group,omitempty"`
	// description: |
	//   运行数据库的操作系统用户密码
	//   该字段不支持明文填写，需使用 ptk encrypt 加密
	//   默认和 global.user_password 配置一致
	// supported_from: v0.5
	UserPassword string `yaml:"user_password,omitempty" json:"user_password,omitempty"`
	// description: |
	//   数据库端口
	//   默认为空，复用全局的端口配置 26000
	// supported_from: v0.1
	DBPort int `yaml:"db_port,omitempty" json:"db_port,omitempty"`
	// description: |
	//   数据库冗余IP，目前最多配置一个冗余IP，如果配置了该字段，所有实例都需要配置
	// supported_from: v0.1
	HAIPs []string `yaml:"ha_ips,omitempty" json:"ha_ips,omitempty"`
	// description: |
	//   数据库主备实例日志复制端口，值固定只能为数据库端口加1，该字段无需配置
	// supported_from: v0.1
	HAPort int `yaml:"ha_port,omitempty" json:"ha_port,omitempty"`
	// description: |
	//   数据库实例角色，若不填，PTK 会随机选择一个实例作为主库，其余自动为备库
	// values:
	//   - primary
	//   - standby
	//   - cascade_standby
	// supported_from: v0.1
	Role string `yaml:"role,omitempty" json:"role,omitempty"`
	// description: |
	//   当实例角色为 cascade_standby 时，该字段表示要跟随的上游备库 IP
	// supported_from: v0.1
	UpstreamHost string `yaml:"upstream_host,omitempty" json:"upstream_host,omitempty"`
	// description: |
	//   Available Zone (可用区) 名称
	//   默认值："AZ1"
	// supported_from: v0.1
	AzName string `yaml:"az_name,omitempty" json:"az_name,omitempty"`
	// description: |
	//   可用区使用的优先级，数值越小优先级越高, 最小为 1
	//   默认值：1
	AzPriority int `yaml:"az_priority,omitempty" json:"az_priority,omitempty"`
	// description: |
	//   数据库 Xlog 日志目录设置
	//   默认为空，若需配置，值不能为数据目录的子目录
	// supported_from: v0.1
	XLogDir string `yaml:"xlog_dir,omitempty" json:"x_log_dir,omitempty"`
	// description: |
	//   用户根据个性化需要配置数据库参数和值，该字段配置的内容将会在数据库启动前写入到 postgresql.conf 文件中
	// examples:
	//   - name: db config example
	//     value: >
	//        map[string]string{
	//          "key": "value",
	//        }
	// supported_from: v0.1
	DBConf map[string]string `yaml:"db_conf,omitempty" json:"db_conf,omitempty"`
	// description: |
	//   用户可根据需要针对该实例增加特定的环境变量
	// supported_from: v1.2.0
	EnvMap map[string]string `yaml:"env_map,omitempty" json:"env_map,omitempty"`
	// description: |
	//   SSH 登录信息，登录用户需为 **root** 或者具有 sudo 权限的用户
	//   不设置时为本地执行
	// supported_from: v0.1
	SSHOption *SSHOption `yaml:"ssh_option,omitempty" json:"ssh_option,omitempty"`
}

type SSHOption struct {
	//  description: |
	//    要连接的目标服务器 IP
	//    当该机器为跳板机时必填；
	//    当为数据库所在机器时可以留空，会继承 db_server 的 IP
	//    默认为空
	Host string `yaml:"host,omitempty" json:"host,omitempty"`
	//  description: |
	//    SSH 服务端口
	//    默认值：22
	Port int `yaml:"port,omitempty" json:"port,omitempty"`
	//  description: |
	//    SSH 登录用户
	//    默认值：root
	User string `yaml:"user,omitempty" json:"user,omitempty"`
	//  description: |
	//    SSH 登录用户密码
	//    该字段不支持明文填写，需使用 ptk encrypt 加密后填写
	//  examples:
	//    - name: ssh 密码示例
	//      value: '"pTk6MTIxOGMxOTk8QT1CPT4+PXlnYW1DdHpXb2hCX3c3UW0wWXVkNlZwMGRCakpxRXd1WWdwQ0xDUWVrb0U="'
	Password string `yaml:"password,omitempty" json:"password,omitempty"`
	//  description: |
	//    SSH 登录密钥文件路径
	//    默认为空
	//  examples:
	//    - name: ssh密钥示例
	//      value: '"~/.ssh/id_rsa"'
	KeyFile string `yaml:"key_file,omitempty" json:"key_file,omitempty"`
	//  description: |
	//    SSH 登录密钥文件口令
	//    该字段不支持明文填写，需使用 ptk encrypt 加密后填写
	//    默认为空
	Passphrase string `yaml:"passphrase,omitempty" json:"passphrase,omitempty"`
	//  description: |
	//    SSH 登录连接超时时间，支持单位 m(分),s(秒)
	//    默认值: "1m"
	ConnTimeout time.Duration `yaml:"conn_timeout,omitempty" json:"conn_timeout,omitempty"`
	//  description: |
	//    SSH 执行单条命令时的超时时间，支持单位 m(分),s(秒)
	//    默认值: "10m"
	ExecTimeout time.Duration `yaml:"exec_timeout,omitempty" json:"exec_timeout,omitempty"`
	//  description: |
	//    跳板服务器登录信息，如果目标服务器无法直连时，支持通过中间跳板机方式连接
	Proxy *SSHOption `yaml:"proxy,omitempty" json:"proxy,omitempty"`
	//  description: 网卡名称(IPv6时必填，ipv6支持还不完善，不开放设置)
	// docgen:nodoc
	NicName string `yaml:"nic_name,omitempty" json:"nic_name,omitempty"`
	// 备用连接 IP
	// docgen:nodoc
	AlternateIPs []string `yaml:"alternate_ips,omitempty" json:"alternate_ips,omitempty"`
}
type CMServer struct {
	// description: |
	//   CM Server 服务器 IP (仅支持 IPv4)
	// supported_from: v0.5
	Host string `yaml:"host" json:"host"`
	// description: |
	//   数据库冗余IP，和当前 host 对应的 db_server 中的 ha_ips 保持一致
	// supported_from: v1.1.0
	HAIPs []string `yaml:"ha_ips,omitempty" json:"ha_ips,omitempty"`
	// description: |
	//   CM Server 监听端口
	//   默认使用 global.cm_option.cm_server_port
	// supported_from: v0.5
	Port int `yaml:"port" json:"port"`
	// description: |
	//   SSH 登录信息，登录用户需为 **root** 或者具有 sudo 权限的用户
	//   不设置时为本地执行
	// supported_from: v0.5
	SSHOption *SSHOption `yaml:"ssh_option,omitempty" json:"ssh_option,omitempty"`
}

type CMOption struct {
	// description: |
	//   CM 安装目录
	//   默认值: $base_dir/cm
	// supported_from: v0.4
	Dir string `yaml:"dir" json:"dir,omitempty"`
	// description: |
	//   cm server 监听端口
	//   默认值: 15300
	// supported_from: v0.4
	CmServerPort int `yaml:"cm_server_port,omitempty" json:"cm_server_port,omitempty"`
	// docgen:nodoc
	// 不提供配置，目前仅支持 1
	CmServerLevel int `yaml:"cm_server_level,omitempty" json:"cm_server_level,omitempty"`
	// description: 数据库提供服务的虚拟IP
	// supported_from: v0.4
	DBServiceVIP string `yaml:"db_service_vip" json:"db_service_vip,omitempty"`
	// description: |
	//   cm_server.conf 中支持的配置参数， PTK 不对参数的准确性和有效性做校验
	// examples:
	//   - name: cm server conf
	//     value: >
	//        map[string]string{
	//          "key": "value",
	//        }
	// supported_from: v0.4
	CmServerConf map[string]string `yaml:"cm_server_conf,omitempty" json:"cm_server_conf,omitempty"`
	// description: |
	//   cm_agent.conf 中支持的配置参数， PTK 不对参数的准确性和有效性做校验
	// examples:
	//   - name: cm agent conf
	//     value: >
	//        map[string]string{
	//          "key": "value",
	//        }
	// supported_from: v0.4
	CmAgentConf map[string]string `yaml:"cm_agent_conf,omitempty" json:"cm_agent_conf,omitempty"`
}

type HBAConf struct {
	// description: |
	//   连接类型，支持 local/host/hostssl/hostnossl
	//   具体含义请参考 MogDB 文档: https://docs.mogdb.io/zh/mogdb/v5.0/1-client-access-authentication#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E5%8F%82%E8%80%83
	//   默认值: host
	// supported_from: v1.5.0
	Type string `yaml:"type,omitempty"`
	// description: |
	//   指定这条记录所匹配的数据库名称
	//   默认值: all
	// supported_from: v1.5.0
	Database string `yaml:"database,omitempty"`
	// description: |
	//   指定这条记录匹配哪些数据库用户名
	//   默认值: all
	// supported_from: v1.5.0
	User string `yaml:"user,omitempty"`
	// description: |
	//   必填，指定这个记录匹配的客户端机器地址。
	//   如果只设置一个IPv4或IPv6地址，未配置 CIDR 掩码，则默认针对 IPv4 使用 32 的 CIDR 掩码，针对 IPv6 使用 128 的 CIDR 掩码
	// supported_from: v1.5.0
	Address string `yaml:"address,omitempty"`
	// description: |
	//   指定当一个连接匹配这个记录时，要使用的认证方法。
	//   默认值: sha256
	// supported_from: v1.5.0
	Method string `yaml:"method,omitempty"`
	// description: |
	//   在 method 域的后面，可以是形如 name=value 的域，它们指定认证方法的选项
	// supported_from: v1.5.0
	Option string `yaml:"option,omitempty"`
}
